package cn.skylark.wcm.common.splitter.doc;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
import org.apache.poi.xwpf.converter.core.FileURIResolver;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.w3c.dom.Document;
import org.zwobble.mammoth.DocumentConverter;
import org.zwobble.mammoth.Result;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

//import org.apache.poi.hwpf.converter.WordToHtmlConverter;

public class POIConverter {

    private static String html_header = "<html><head><meta http-equiv=\"content-type\" content=\"text/html\" charset=\"UTF-8\"/></head><body>";
    private static String html_footer = "</body></html>";

    /*
     * 将一个或者目录下的所有doc/docx文件转换为html，支持子目录。
     */
    public String parse2html(String filename, String outpath, Integer[] splitparas) throws Throwable {
        File file = new File(filename);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateFile = sdf.format(date);
        String outPath = outpath+"_"+dateFile;
        if (file.isDirectory()) {
            for (File eachfile : file.listFiles()) {
                if (eachfile.isDirectory()) {
                    File dir = new File(outpath + eachfile.getName() + "/");
                    dir.mkdir();
                    parse2html(eachfile.getPath(), dir.getPath() + "/", splitparas);
                } else {
                    final String path = eachfile.getParent();
                    try {
                        InputStream input = new FileInputStream(eachfile);
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    int tempposition = eachfile.getName().indexOf("doc");
                    if (tempposition != -1) {
                        String suffix = eachfile.getName().substring(tempposition); //截取文件格式名
                        if (suffix.equalsIgnoreCase("doc")) {
                            try {
                                parseDoc2Html(eachfile.getPath(), outpath, splitparas);
                            } catch (Throwable e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        } else if (suffix.equalsIgnoreCase("docx")) {
                            try {
                                parseDocx2HtmlMammoth(eachfile.getPath(), outpath);
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        } else {
            //不是文件夹的
            int tempposition = file.getName().indexOf("doc");
            if (tempposition != -1) {
                String suffix = file.getName().substring(tempposition);
                //截取文件格式名
                if (suffix.equalsIgnoreCase("doc")) {
                    try {
                        parseDoc2Html(file.getPath(), outPath, splitparas);
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                } else if (suffix.equalsIgnoreCase("docx")) {
                    try {
                        parseDocx2HtmlMammoth(file.getPath(), outpath);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return  dateFile;
    }

    /*
     * 将一个或者目录下的所有doc/docx文件转换为txt文件，支持子目录。并生成一个大的txt文件。
     * 输入 outpath 为输出文本文件的目录
     */
    public void parse2text(String filename, String outpath, String bigtxtfile) {
        File file = new File(filename);
//        System.out.println("Processing file: " + file.getName());

        //输入为目录
        if (file.isDirectory()) {
            for (File eachfile : file.listFiles()) {
                if (eachfile.isDirectory()) {
//                    System.out.println(eachfile.getPath() + " is a directory, looping in!");
                    File dir = new File(outpath + eachfile.getName() + "\\");
                    dir.mkdir();
                    parse2text(eachfile.getPath(), dir.getPath() + "\\", bigtxtfile);
                } else {
                    if (eachfile.getName().endsWith(".doc") || eachfile.getName().endsWith(".DOC")) {
//                        System.out.println("The file " + eachfile.getPath() + " is a DOC file!");
                        try {
                            parseDoc2TextPOI(eachfile.getPath(), outpath, bigtxtfile);
                        } catch (Throwable e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    } else if (eachfile.getName().endsWith(".docx") || eachfile.getName().endsWith(".DOCX")) {
//                        System.out.println("The file " + eachfile.getPath() + " is a DOCX file!");
                        try {
                            parseDocx2TextMammoth(eachfile.getPath(), outpath, bigtxtfile);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    } else {
//                        System.out.println("The file " + eachfile.getPath() + "'s extension is not DOC or DOCX!");
                    }
                }
            }
        }
        //输入为文件
        else {
            if (file.getName().endsWith(".doc") || file.getName().endsWith(".DOC")) {
//                System.out.println("The file " + file.getPath() + " is a DOC file!");
                try {
                    parseDoc2TextPOI(file.getPath(), outpath, bigtxtfile);
                } catch (Throwable e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if (file.getName().endsWith(".docx") || file.getName().endsWith(".DOCX")) {
//                System.out.println("The file " + file.getPath() + " is a DOCX file!");
                try {
                    parseDocx2TextMammoth(file.getPath(), outpath, bigtxtfile);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else {
//                System.out.println("The file " + file.getPath() + "'s extension is not DOC or DOCX!");
            }
        }
    }


    //输入word文件的文件名，转换为同目录下的html文件。
    public void parseDoc2Html(String filename, String outpath, Integer[] splitpara) throws Throwable {

        File file = new File(filename);
        if (outpath.isEmpty()) {
            outpath = file.getParent();
        }
        InputStream is = new FileInputStream(filename);
        HWPFDocument doc = new HWPFDocument(is);
        Range range = doc.getRange();
        //判断是否存在该路径，不存在的话进行新建
        File folder = new File(outpath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        //String suffix = file.getName().substring(file.getName().indexOf("doc"));// //截取文件格式名

        //实例化WordToHtmlConverter，为图片等资源文件做准备

        if (file.getName().endsWith(".doc") || file.getName().endsWith(".DOC")) {
            InputStream input = new FileInputStream(file);
            HWPFDocument wordDocument = new HWPFDocument(input);

            //处理文档中所有的图片，会在同目录下生成 images 路径并保存图片
            List pics = wordDocument.getPicturesTable().getAllPictures();
            if (pics != null) {
                for (int i = 0; i < pics.size(); i++) {
                    Picture pic = (Picture) pics.get(i);
                    try {
                        //创建目录文件;
                        pic.writeImageContent(new FileOutputStream(outpath + "/" + pic.suggestFullFileName()));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }

            //测试文档分拆的段落分布 0-12, 13-23
            //将这段替换为实际拆分段落的代码
            //循环处理每个拆分文件
            for (int j = 0; j < splitpara.length - 1; j++) {
                Paragraph paragraph = range.getParagraph(splitpara[j]);
                //每次需要新的WordToHtmlConverter，新建时内部会初始化一个private final HtmlDocumentFacade htmlDocumentFacade来保存HTML输出
                WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                        DocumentBuilderFactory.newInstance().newDocumentBuilder()
                                .newDocument());
                wordToHtmlConverter.setPicturesManager(new PicturesManager() {
                    public String savePicture(byte[] content, PictureType pictureType,
                                              String suggestedName, float widthInches, float heightInches) {
                        return suggestedName;
                    }
                });
                //对于每个拆分文件，处理word文档内容
                //processDocument传入参数：
                //1. document
                //2. 分拆分布数组，第一个为0，第二个为第二段落开始序号，第三个为第三个段落开始序号，以此类推，最后一个为段落总数+1。
                //3. 分拆文件序号，从0开始。
                wordToHtmlConverter.processDocument(wordDocument, splitpara, j);

                // 转换
                Document htmlDocument = wordToHtmlConverter.getDocument();
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                DOMSource domSource = new DOMSource(htmlDocument);
                StreamResult streamResult = new StreamResult(outStream);
                TransformerFactory tf = TransformerFactory.newInstance();
                Transformer serializer = tf.newTransformer();
                serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");//编码格式
                serializer.setOutputProperty(OutputKeys.INDENT, "yes");//是否用空白分割
                serializer.setOutputProperty(OutputKeys.METHOD, "html");//输出类型
                serializer.transform(domSource, streamResult);
                outStream.close();
                String content = new String(outStream.toByteArray());
                content = POIConverter.html_header + content + this.html_footer;
                String name = (paragraph.text()).trim();
                String oldfile;
                if (name.contains(" ")){
                    oldfile =  name.substring(name.lastIndexOf(" "));
                }else{
                    oldfile = name;
                }
                oldfile = oldfile.replaceAll("/","-");
                String htmlname = outpath + "/" + oldfile + ".html";
                File newFile = new File(outpath + File.separator + oldfile+".html");
                if (newFile.exists()) {
                    newFile.delete();
                }
                FileUtils.writeStringToFile(new File(htmlname), content, "utf-8");
                //开始txt的拆分
            }
//            System.out.println("file:" + filename + " converted");

        } else {
//            System.out.println("File " + file + " is not a doc files");
        }
    }

    //输出docx到html，用poi
    public static void parseDocx2HtmlPOI(String filename) throws IOException {
        File file = new File(filename);
        if (!file.exists()) {
//            System.out.println("Sorry File does not Exists!");
        } else {
            if (file.getName().endsWith(".docx") || file.getName().endsWith(".DOCX")) {
                String path = file.getParent();
                String htmlname = Util.removedocfilextension(file) + "html";
                // 1) 加载XWPFDocument及文件
                InputStream in = new FileInputStream(file);
                XWPFDocument document = new XWPFDocument(in);

                // 2) 实例化XHTML内容(这里将会把图片等文件放到生成的"word/media"目录)
                File imageFolderFile = new File(path);
                XHTMLOptions options = XHTMLOptions.create().URIResolver(new FileURIResolver(imageFolderFile));
                options.setExtractor(new FileImageExtractor(imageFolderFile));
                // 3) 将XWPFDocument转成XHTML并生成文件
                OutputStream out = new FileOutputStream(new File(htmlname));
                XHTMLConverter.getInstance().convert(document, out, null);
            } else {
//                System.out.println("Enter only MS Office 2007+ files");
            }
        }
    }

    //输出docx到html，用mammoth
    public static void parseDocx2HtmlMammoth(String filename, String outpath) throws IOException {
        //输出docx到html，用mammoth
        Util util = new Util();
        File file = new File(filename);
        DocumentConverter converter = new DocumentConverter();
        Result<String> result = null;
        Result<String> textresult = null;
        try {
            result = converter.convertToHtml(file);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String html = result.getValue(); // The generated HTML

        String name = file.getName().substring(0, file.getName().indexOf("doc"));
        String targethtml = outpath + "\\" + name + "html";

        //String rawname=util.removedocextension(filename);
        //String targethtml=rawname+".html";

        String html_header = "<html><head><meta http-equiv=\"content-type\" content=\"text/html\" charset=\"UTF-8\"/></head><body>";
        String html_footer = "</body></html>";

        html = html_header + html + html_footer;

        try {
            FileWriter writer = new FileWriter(targethtml);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.write(html);
            bufferedWriter.flush();
            bufferedWriter.close();
//            System.out.println("File " + filename + " converted");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    //输出docx到text，用mammoth
    public static void parseDocx2TextMammoth(String filename, String outpath, String bigtxtfile) throws IOException {
        //输出docx到html，用mammoth
        Util util = new Util();
        File file = new File(filename);
        DocumentConverter converter = new DocumentConverter();
        Result<String> result = null;
        Result<String> textresult = null;
        try {
            result = converter.extractRawText(file);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String text = result.getValue(); // The generated Text

        //将所有转换的文件写入一个文本文件用于建立词向量
        Util.writeFile(text.trim(), bigtxtfile, true);

        String targetfile;
        if (outpath.isEmpty()) {
            String rawname = util.removedocextension(filename);
            targetfile = rawname + ".txt";
        } else {
            if (file.getName().indexOf("doc") != -1) {
                String name = file.getName().substring(0, file.getName().indexOf("doc"));
                targetfile = outpath + name + "txt";
            } else {
                targetfile = outpath + file.getName() + "txt";
            }

        }

        try {
            FileWriter writer = new FileWriter(targetfile);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.write(text.trim());
            bufferedWriter.flush();
            bufferedWriter.close();
//            System.out.println("File " + filename + " converted");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    //将doc文件转换分为text文件
    /*
     * 输入：
     * 	filename	需要转换的doc文件
     * 	outpath		输出文本文件的目录
     *
     * 输出：
     * 	将doc文件转换为文本文件保存在outpath中，如outpath为空，则保存在doc文件的同目录下
     */
    public void parseDoc2TextPOI(String filename, String outpath, String bigtxtfile) throws Throwable {
        File file = new File(filename);
        //Util util=new Util();
//        System.out.println("Processing File " + filename + ". The output path is" + outpath);
        String targetfile = null;

        if (file.getName().endsWith(".doc") || file.getName().endsWith(".DOC")) {
            //create directory for the convert
            if (outpath.isEmpty()) {
                //outpath = file.getParent();
                targetfile = Util.removedocextension(filename) + "txt";
            } else {
                if (file.getName().indexOf("doc") != -1) {
                    String name = file.getName().substring(0, file.getName().indexOf("doc"));
                    targetfile = outpath + name + "txt";
                } else {
                    targetfile = outpath + file.getName() + "txt";
                }
            }


//            System.out.println("The output path is " + outpath);

            try {
                InputStream input = new FileInputStream(file);
                HWPFDocument doc = new HWPFDocument(input);

                StringBuilder sb = doc.getText();
                String text = sb.toString();

                //写入单独的文本文件
                Util.writeFile(text.trim(), targetfile, false);

                //写入到word2vec用的大文件
                Util.writeFile(text.trim(), bigtxtfile, true);
                input.close();
                doc.close();
//                System.out.println("File " + filename + " has been coverted to " + outpath);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}


